<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>条码扫描</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: #f5f7fa;
            min-height: 100vh;
            color: #333;
        }
        
        .container {
            max-width: 100%;
            margin: 0;
            padding: 20px;
        }
        
        .header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 20px;
            text-align: center;
            border-radius: 15px;
            margin-bottom: 20px;
        }
        
        .scanner-container {
            background: white;
            border-radius: 15px;
            padding: 20px;
            box-shadow: 0 5px 20px rgba(0, 0, 0, 0.1);
            text-align: center;
        }
        
        #video {
            width: 100%;
            max-width: 300px;
            height: 200px;
            border: 2px solid #667eea;
            border-radius: 10px;
            margin: 20px auto;
            display: block;
        }
        
        .scan-button {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            padding: 12px 30px;
            border-radius: 25px;
            font-size: 16px;
            font-weight: 600;
            cursor: pointer;
            margin: 10px;
            transition: all 0.3s ease;
        }
        
        .scan-button:active {
            transform: scale(0.95);
        }
        
        .scan-button:disabled {
            background: #ccc;
            cursor: not-allowed;
        }
        
        .result {
            margin-top: 20px;
            padding: 15px;
            background: #f8f9fa;
            border-radius: 10px;
            border-left: 4px solid #667eea;
        }
        
        .result h3 {
            color: #333;
            margin-bottom: 10px;
        }
        
        .result p {
            color: #666;
            word-break: break-all;
        }
        
        .error {
            color: #e74c3c;
            background: #fdf2f2;
            border-left-color: #e74c3c;
        }
        
        .success {
            color: #27ae60;
            background: #f2fdf4;
            border-left-color: #27ae60;
        }
        
        .loading {
            text-align: center;
            padding: 20px;
            color: #666;
        }
        
        .methods {
            margin-top: 30px;
            text-align: center;
        }
        
        .methods h3 {
            margin-bottom: 15px;
            color: #333;
        }
        
        .method-button {
            background: white;
            border: 2px solid #667eea;
            color: #667eea;
            padding: 8px 20px;
            border-radius: 20px;
            margin: 5px;
            cursor: pointer;
            transition: all 0.3s ease;
        }
        
        .method-button:hover {
            background: #667eea;
            color: white;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>📱 条码扫描</h1>
            <p>支持二维码、条形码扫描</p>
        </div>
        
        <div class="scanner-container">
            <video id="video" style="display: none;"></video>
            <canvas id="canvas" style="display: none;"></canvas>
            
            <div id="loading" class="loading" style="display: none;">
                正在启动摄像头...
            </div>
            
            <div id="controls">
                <button id="startBtn" class="scan-button">开始扫描</button>
                <button id="stopBtn" class="scan-button" style="display: none;">停止扫描</button>
            </div>
            
            <div id="result" class="result" style="display: none;">
                <h3>扫描结果</h3>
                <p id="resultText"></p>
            </div>
        </div>
        
        <div class="methods">
            <h3>其他扫描方式</h3>
            <button id="wechatBtn" class="method-button">微信扫码</button>
            <button id="uploadBtn" class="method-button">上传图片</button>
            <input type="file" id="fileInput" accept="image/*" style="display: none;">
        </div>
    </div>

    <!-- 使用ZXing库进行条码扫描 -->
    <script src="https://unpkg.com/@zxing/library@latest"></script>
    <script>
        class BarcodeScanner {
            constructor() {
                this.codeReader = new ZXing.BrowserMultiFormatReader();
                this.isScanning = false;
                this.stream = null;
                
                this.initElements();
                this.bindEvents();
            }
            
            initElements() {
                this.video = document.getElementById('video');
                this.canvas = document.getElementById('canvas');
                this.startBtn = document.getElementById('startBtn');
                this.stopBtn = document.getElementById('stopBtn');
                this.result = document.getElementById('result');
                this.resultText = document.getElementById('resultText');
                this.loading = document.getElementById('loading');
                this.wechatBtn = document.getElementById('wechatBtn');
                this.uploadBtn = document.getElementById('uploadBtn');
                this.fileInput = document.getElementById('fileInput');
            }
            
            bindEvents() {
                this.startBtn.addEventListener('click', () => this.startScanning());
                this.stopBtn.addEventListener('click', () => this.stopScanning());
                this.wechatBtn.addEventListener('click', () => this.wechatScan());
                this.uploadBtn.addEventListener('click', () => this.fileInput.click());
                this.fileInput.addEventListener('change', (e) => this.scanFromFile(e));
            }
            
            async startScanning() {
                try {
                    this.showLoading(true);
                    this.hideResult();
                    
                    // 请求摄像头权限
                    this.stream = await navigator.mediaDevices.getUserMedia({
                        video: { facingMode: 'environment' } // 优先使用后置摄像头
                    });
                    
                    this.video.srcObject = this.stream;
                    this.video.style.display = 'block';
                    
                    // 等待视频加载
                    await new Promise(resolve => {
                        this.video.onloadedmetadata = resolve;
                    });
                    
                    this.video.play();
                    
                    // 开始扫描
                    this.isScanning = true;
                    this.startBtn.style.display = 'none';
                    this.stopBtn.style.display = 'inline-block';
                    
                    this.scanLoop();
                    
                } catch (error) {
                    this.showError('无法访问摄像头: ' + error.message);
                } finally {
                    this.showLoading(false);
                }
            }
            
            scanLoop() {
                if (!this.isScanning) return;
                
                try {
                    const result = this.codeReader.decodeFromCanvas(this.video);
                    if (result) {
                        this.showResult(result.text);
                        this.stopScanning();
                        return;
                    }
                } catch (error) {
                    // 继续扫描
                }
                
                requestAnimationFrame(() => this.scanLoop());
            }
            
            stopScanning() {
                this.isScanning = false;
                
                if (this.stream) {
                    this.stream.getTracks().forEach(track => track.stop());
                    this.stream = null;
                }
                
                this.video.style.display = 'none';
                this.startBtn.style.display = 'inline-block';
                this.stopBtn.style.display = 'none';
            }
            
            async scanFromFile(event) {
                const file = event.target.files[0];
                if (!file) return;
                
                try {
                    this.showLoading(true);
                    
                    const img = new Image();
                    img.onload = () => {
                        const canvas = document.createElement('canvas');
                        const ctx = canvas.getContext('2d');
                        
                        canvas.width = img.width;
                        canvas.height = img.height;
                        ctx.drawImage(img, 0, 0);
                        
                        try {
                            const result = this.codeReader.decodeFromCanvas(canvas);
                            if (result) {
                                this.showResult(result.text);
                            } else {
                                this.showError('无法识别图片中的条码');
                            }
                        } catch (error) {
                            this.showError('无法识别图片中的条码');
                        }
                        
                        this.showLoading(false);
                    };
                    
                    img.src = URL.createObjectURL(file);
                    
                } catch (error) {
                    this.showError('处理图片时出错: ' + error.message);
                    this.showLoading(false);
                }
                
                // 清空文件输入
                event.target.value = '';
            }
            
            wechatScan() {
                if (typeof wx !== 'undefined' && wx.scanQRCode) {
                    wx.scanQRCode({
                        needResult: 1,
                        scanType: ["qrCode", "barCode"],
                        success: (res) => {
                            this.showResult(res.resultStr);
                        },
                        fail: (error) => {
                            this.showError('微信扫码失败: ' + error.errMsg);
                        }
                    });
                } else {
                    alert('请在微信中使用此功能');
                }
            }
            
            showResult(text) {
                this.resultText.textContent = text;
                this.result.className = 'result success';
                this.result.style.display = 'block';
            }
            
            showError(message) {
                this.resultText.textContent = message;
                this.result.className = 'result error';
                this.result.style.display = 'block';
            }
            
            hideResult() {
                this.result.style.display = 'none';
            }
            
            showLoading(show) {
                this.loading.style.display = show ? 'block' : 'none';
            }
        }
        
        // 初始化扫描器
        document.addEventListener('DOMContentLoaded', () => {
            new BarcodeScanner();
        });
    </script>
</body>
</html>